package com.hhh.springai_test.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhh.springai_test.common.ErrorCode;
import com.hhh.springai_test.constant.UserConstant;
import com.hhh.springai_test.exception.BusinessException;
import com.hhh.springai_test.mapper.BookBorrowMapper;
import com.hhh.springai_test.model.dto.bookborrow.BookBorrowAddRequest;
import com.hhh.springai_test.model.dto.bookborrow.BookBorrowQueryRequest;
import com.hhh.springai_test.model.dto.bookborrow.BookBorrowUpdateRequest;
import com.hhh.springai_test.model.enums.BookBorrowStatusEnum;
import com.hhh.springai_test.model.po.Book;
import com.hhh.springai_test.model.po.BookBorrow;
import com.hhh.springai_test.model.po.User;
import com.hhh.springai_test.model.vo.BookBorrowVO;
import com.hhh.springai_test.model.vo.UserVo;
import com.hhh.springai_test.service.BookBorrowService;
import com.hhh.springai_test.service.BookService;
import com.hhh.springai_test.service.UserService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 29915
* @description 针对表【book_borrow(图书借阅表)】的数据库操作Service实现
* @createDate 2025-02-05 12:26:11
*/
@Service
public class BookBorrowServiceImpl extends ServiceImpl<BookBorrowMapper, BookBorrow>
    implements BookBorrowService {

    @Resource
    private UserService userService;

    @Resource
    private BookService bookService;

    @Override
    public boolean addBookBorrows(List<BookBorrowAddRequest> bookBorrowAddRequests, Long userId) {
        if (bookBorrowAddRequests == null || bookBorrowAddRequests.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        List<BookBorrow> bookBorrows = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date currentDate = new Date();
        
        // 设置时间为当天的0点
        try {
            currentDate = dateFormat.parse(dateFormat.format(currentDate));
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "日期格式化错误");
        }

        for (BookBorrowAddRequest addRequest : bookBorrowAddRequests) {
            if (addRequest == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            // 检查用户是否存在
            if (userService.getById(userId) == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
            }
            Book book = bookService.getById(addRequest.getBookid());
            if (book == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "书籍不存在");
            }
            // 检查借阅时间和归还时间是否合法
            Date borrowTime, returnTime;
            try {
                borrowTime = dateFormat.parse(dateFormat.format(addRequest.getBorrowtime()));
                returnTime = dateFormat.parse(dateFormat.format(addRequest.getReturntime()));
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "日期格式错误");
            }
            if (borrowTime.before(currentDate)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "借阅日期不能小于当前日期");
            }
            if (returnTime.before(borrowTime)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "归还日期不能小于借阅日期");
            }

            // 计算借阅天数
            long diffInMillies = returnTime.getTime() - borrowTime.getTime();
            int borrowDays = (int) (diffInMillies / (1000 * 60 * 60 * 24));

            // 检查借阅天数是否超过一个月
            if (borrowDays > 30) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "借阅时间不能超过一个月");
            }

            QueryWrapper<Book> wrapper = new QueryWrapper<>();
            wrapper.eq("id", addRequest.getBookid());
            wrapper.eq("bookname", addRequest.getBookname());

            if (bookService.count(wrapper) == 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书不存在");
            }

            // 检查是否已借阅该书籍
            QueryWrapper<BookBorrow> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("bookname", addRequest.getBookname())
                    .eq("userid", userId)
                    .in("status", 
                        BookBorrowStatusEnum.BORROWING.getValue(),
                        BookBorrowStatusEnum.PENDING.getValue(),
                        BookBorrowStatusEnum.RENEWED.getValue());

            long count = this.count(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "已借阅该书籍或有待审核的借阅申请");
            }

            BookBorrow bookBorrow = new BookBorrow();
            bookBorrow.setBookid(addRequest.getBookid());
            bookBorrow.setUserid(userId);
            bookBorrow.setBookname(addRequest.getBookname());
            bookBorrow.setBorrowdays(borrowDays);
            User user = userService.getById(userId);
            String userRole = user.getUserRole();
            if (UserConstant.ADMIN_ROLE.equals(userRole)) {
                bookBorrow.setStatus(BookBorrowStatusEnum.BORROWING.getValue());  // 设置为借阅中状态
            } else {
                bookBorrow.setStatus(BookBorrowStatusEnum.PENDING.getValue());  // 设置为待审核状态
            }
            // 设置借阅时间和应还时间
            bookBorrow.setBorrowtime(borrowTime);
            bookBorrow.setShouldreturntime(returnTime);
            Date now = new Date();
            bookBorrow.setCreatetime(now);
            bookBorrow.setUpdatetime(now);
            bookBorrows.add(bookBorrow);
        }

        return this.saveBatch(bookBorrows);
    }

    @Override
    public boolean updateBookBorrow(BookBorrowUpdateRequest updateRequest, Long userId) {
        if (updateRequest == null || updateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        User user = userService.getById(userId);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
        }

        BookBorrow bookBorrow = this.getById(updateRequest.getId());
        if (bookBorrow == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 检查用户权限
        String userRole = user.getUserRole();
        if (!UserConstant.ADMIN_ROLE.equals(userRole)) {
            throw new BusinessException(ErrorCode.NOT_AUTH_CODE, "只有管理员才能修改借阅状态");
        }

        bookBorrow.setStatus(updateRequest.getStatus());
        bookBorrow.setUpdatetime(new Date());

        return this.updateById(bookBorrow);
    }

    @Override
    public Page<BookBorrowVO> listBookBorrowByPage(BookBorrowQueryRequest queryRequest) {
        if (queryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        QueryWrapper<BookBorrow> queryWrapper = new QueryWrapper<>();
        
        if (StringUtils.isNotBlank(queryRequest.getBookname())) {
            queryWrapper.like("bookname", queryRequest.getBookname());
        }
        
        if (queryRequest.getBookid() != null && queryRequest.getBookid() > 0) {
            queryWrapper.eq("bookid", queryRequest.getBookid());
        }

        // 获取原始分页数据
        Page<BookBorrow> bookBorrowPage = this.page(
            new Page<>(queryRequest.getCurrent(), queryRequest.getPageSize()),
            queryWrapper
        );

        // 转换为VO对象
        Page<BookBorrowVO> voPage = new Page<>(
            bookBorrowPage.getCurrent(),
            bookBorrowPage.getSize(),
            bookBorrowPage.getTotal()
        );

        List<BookBorrowVO> voList = bookBorrowPage.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public Page<BookBorrowVO> listUserBookBorrows(BookBorrowQueryRequest queryRequest, Long userId) {
        if (queryRequest == null || userId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        QueryWrapper<BookBorrow> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userid", userId);
        
        if (StringUtils.isNotBlank(queryRequest.getBookname())) {
            queryWrapper.like("bookname", queryRequest.getBookname());
        }
        
        if (queryRequest.getBookid() != null && queryRequest.getBookid() > 0) {
            queryWrapper.eq("bookid", queryRequest.getBookid());
        }

        queryWrapper.orderByDesc("createtime");

        // 获取原始分页数据
        Page<BookBorrow> bookBorrowPage = this.page(
            new Page<>(queryRequest.getCurrent(), queryRequest.getPageSize()),
            queryWrapper
        );

        // 转换为VO对象
        Page<BookBorrowVO> voPage = new Page<>(
            bookBorrowPage.getCurrent(),
            bookBorrowPage.getSize(),
            bookBorrowPage.getTotal()
        );

        List<BookBorrowVO> voList = bookBorrowPage.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    // 添加转换方法
    private BookBorrowVO convertToVO(BookBorrow bookBorrow) {
        if (bookBorrow == null) {
            return null;
        }
        
        BookBorrowVO vo = new BookBorrowVO();
        BeanUtils.copyProperties(bookBorrow, vo);
        
        // 获取用户信息并转换为UserVO
        User user = userService.getById(bookBorrow.getUserid());
        if (user != null) {
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(user, userVo);
            vo.setUser(userVo);
        }
        
        // 获取图书信息并设置图片URL
        Book book = bookService.getById(bookBorrow.getBookid());
        if (book != null) {
            vo.setBookImage(book.getImageurl());
        }
        
        return vo;
    }
}




